package com.nowoe.aop.processor;

import com.nowoe.aop.Advisor;
import com.nowoe.aop.ProceedingJoinPoint;
import com.nowoe.core.bean.BeanFactory;
import com.nowoe.core.bean.BeanPostProcessor;
import com.nowoe.core.proxy.TargetProxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.List;

/**
 * @author 倚栏听风 2023/9/16 14:58
 */
public class ProxyBeanPostProcessor implements BeanPostProcessor {
    List<Advisor> advisors;

    public ProxyBeanPostProcessor(Class<?> aClass) {
        advisors = AspectProcessor.process(aClass);
    }

    @Override
    public void enhance(BeanFactory beanFactory, Object object) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(object.getClass());
        enhancer.setInterfaces(new Class[]{TargetProxy.class});
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                if (method.getName().equals("target") && method.getReturnType().equals(Object.class) && method.getParameterCount() == 0) {
                    return object;//返回原始对象
                }
                ProceedingJoinPoint joinPoint = new ProceedingJoinPoint(advisors, object, method, args);
                return joinPoint.proceed();
            }
        });
        Object o = enhancer.create();
        //用代理对象替换原始对象
        beanFactory.replace(object.getClass(), o);
    }
}
